﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using CodeCounsel.SharePoint.RibbonDesigner.Model;
using System.Collections.ObjectModel;
using System.Windows.Input;
using System.ComponentModel;
using System.Windows.Threading;
using System.Windows;
using System.Collections.Specialized;

namespace CodeCounsel.SharePoint.RibbonDesigner.ViewModel
{
    public class GroupViewModel
        : BaseViewModel
    {
        Group _group;
        ControlContainer _container;
        Layout _currentLayout;
        bool _isPopup;
        public ObservableCollection<GroupSectionBaseViewModel> Sections { get; private set; }

        public string Title
        {
            get { return _group != null ? _group.Title : null; }
            set { _group.Title = value; }
        }

        public RibbonId Id
        {
            get { return _group.Id; }
        }

        public bool IsPopup
        {
            get { return _isPopup; }
            set
            {
                if (value != _isPopup)
                {
                    _isPopup = value;
                    OnPropertyChanged(new PropertyChangedEventArgs("IsPopup"));
                }
            }
        }

        public string LayoutTitle
        {
            get { return _currentLayout.LayoutTitle; }
        }

        public GroupViewModel(Group group)
        {
            _group = group;
            _container = group.Items;
            Sections = new ObservableCollection<GroupSectionBaseViewModel>();
        }

        public GroupViewModel(Group group, Layout layout)
            : this(group)
        {
            SetLayout(layout, false);
        }

        public void SetLayout(Layout layout, bool isPopup)
        {
            Sections.Clear();
            foreach (GroupSectionBaseViewModel section in
                    layout.Sections.SelectMany(s => CreateSectionViewModel(s, _group)))
            {
                Sections.Add(section);
            }
            IsPopup = isPopup;
            _currentLayout = layout;
        }

        void Children_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
        {
            RunUI(delegate
            {
                SetLayout(_currentLayout, IsPopup);
            });
        }
        
        IEnumerable<GroupSectionBaseViewModel> CreateSectionViewModel(
            DomainElement section, Group group)
        {
            Func<string, IEnumerable<Control>> controlSelector =
                templateAlias => ExtensionManager.GetReplacedChildren<Control>(group.Items)
                    .Where(c => c.TemplateAlias == templateAlias);
            if(section is Section)
            {
                return new GroupSectionBaseViewModel[]{ new GroupSectionViewModel(
                    group, (Section)section, controlSelector)};
            }
            else if (section is OverflowSection)
            {
                List<GroupOverflowSectionViewModel> viewModels = new List<GroupOverflowSectionViewModel>();
                OverflowSection flowSection = (OverflowSection)section;
                GroupOverflowSectionViewModel viewModel = null;
                List<Control> items = controlSelector(flowSection.TemplateAlias).ToList();
                //List<Control> items = ExtensionManager.GetReplacedChildren<Control>(group.Controls)
                //    .Where(c => c.TemplateAlias == flowSection.TemplateAlias)
                //    .OrderBy(c => c is ISequential ? ((ISequential)c).Sequence : Int32.MaxValue)
                //    .ToList();
                for (int i = 0; i < items.Count; i++)
    			{
                    BaseViewModel control = ControlViewModelFactory.CreateControlModel(items[i],flowSection.DisplayMode);
                    if (flowSection.Type == SectionType.OneRow)
                    {
                        if (viewModel == null)
                        {
                            viewModel = new GroupOverflowSectionViewModel(flowSection);
                            viewModels.Add(viewModel);
                        }
                        viewModel.Rows[0].Items.Add(control);
                    }
                    else if (flowSection.Type == SectionType.TwoRow)
                    {
                        if (viewModel == null)
                        {
                            viewModel = new GroupOverflowSectionViewModel(flowSection);
                            viewModels.Add(viewModel);
                        }
                        viewModel.Rows[i % 2].Items.Add(control);
                        if (i % 2 == 1)
                        {
                            viewModel = null;
                        }
                    }
                    else if (flowSection.Type == SectionType.ThreeRow)
                    {
                        if (viewModel == null)
                        {
                            viewModel = new GroupOverflowSectionViewModel(flowSection);
                            viewModels.Add(viewModel);
                        }
                        viewModel.Rows[i % 3].Items.Add(control);
                        if (i % 3 == 2)
                        {
                            viewModel = null;
                        }
                    }
    			}
                return viewModels.Cast<GroupSectionBaseViewModel>();
            }
            throw new ArgumentException("section");
        }

        void Group_ControlRemoved(object sender, DomainElementEventArgs<Control> e)
        {
            Control control = e.Element;
            RunUI(delegate
            {
                SetLayout(_currentLayout, IsPopup);
            });
        }

        void Group_ControlContainerRemoved(object sender, DomainElementEventArgs<ControlContainer> e)
        {
            RunUI(delegate
            {
                SetLayout(_currentLayout, IsPopup);
            });
        }

    }
}
